/*
 * @Author:
 * @Date: 2023-03-20 19:27:47
 * @LastEditors: xxx
 * @LastEditTime: 2023-06-05 11:28:41
 * @FilePath: \hart\hart\hart_master.c
 * @Description:
 * email:
 * Copyright (c) 2023 by xxx, All Rights Reserved.
 */

#include "../inc/hart_master.h"
#include "../inc/hart_master_req.h"
#include "../inc/hart_master_rsp.h"

#ifdef MASTER
static hart_master_init_t *handle;

// 内部状态检查
static response_communication_code_e hart_master_state_check(uint8_t command)
{
    //  检查是否开启的写保护
    if (hart_is_write_command(command))
    {
        if (WRITE_PROTECT_CODE_WRITE_PROTECT == hart_master_attribute.io_system.write_protect_code)
        {
            return RESPONSE_COMMUNICATION_CODE_7;
        }
    }
    return RESPONSE_COMMUNICATION_CODE_0;
}

/**
 * @briefhart主机处理函数
 * @param {uint8_t} *rxBuf
 * @param {uint16_t} len
 * @return {*}
 */
BOOL hart_master_handle(uint8_t *rxBuf, uint16_t len)
{
    if (!DBG_ASSERT(rxBuf != NULL __DBG_LINE))
        return FALSE;
    if (!DBG_ASSERT(len != 0 __DBG_LINE))
        return FALSE;
    uint8_t command_length = 0;
    hart_short_address_u poll_address;
    hart_long_address_u long_address;
    hart_delimiter_u delimiter;
    hart_command_rsp_t rsp;
    uint16_t offset = 0;
    uint8_t rsp_len = 0;                              // 响应数据长度
    uint8_t xor = 0;                                  // 异或校验
    uint8_t preamble_def = HART_PREAMBLE_DEFAULT_LEN; // 引导码长度
    uint8_t *data_start_p = NULL;

    delimiter.data = 0;
    osel_memset((uint8_t *)&poll_address, 0, sizeof(hart_short_address_u));
    osel_memset((uint8_t *)&long_address, 0, sizeof(hart_long_address_u));
    osel_memset((uint8_t *)&rsp, 0, sizeof(hart_command_rsp_t));

    handle->response->code = RESPONSE_COMMUNICATION_CODE_0;
    handle->response->data_length = 0;
    handle->response->data_p = handle->response->data;
    osel_memset((uint8_t *)handle->response->data, 0, HART_RESPONSE_MAX_LEN);

    hart_delimiter_u *delimiter_p = (hart_delimiter_u *)&rxBuf[offset];
    rsp.delimiter.data = delimiter_p->data;
    offset++;
    if (delimiter_p->bits.addr_type == HART_DELIMITER_TYPE_SHORT)
    {
        poll_address.data = rxBuf[offset];
        uint8_t tmp = poll_address.bits.slave;
        rsp.address_length = HART_SHORT_ADDRESS_LEN;
        rsp.address[0] = tmp;
    }
    else
    {
        osel_memcpy((uint8_t *)&long_address.data, &rxBuf[offset], sizeof(uint40_t));
        uint8_t tmp[HART_LONG_ADDRESS_LEN];
        osel_memset(tmp, 0, HART_LONG_ADDRESS_LEN);
        tmp[0] = long_address.bits.reserved;
        osel_memcpy(&tmp[1], (uint8_t *)&long_address.bits.slave, 4);
        rsp.address_length = HART_LONG_ADDRESS_LEN;
        osel_memcpy(rsp.address, tmp, HART_LONG_ADDRESS_LEN);
    }
    offset += rsp.address_length;

    // 根据界定符中的扩展字节数量来确定命令码
    command_length = delimiter_p->bits.ext_bytes + 1;
    osel_memcpy((uint8_t *)&rsp.command, &rxBuf[offset], command_length);
    offset += command_length;

    rsp.data_length = rxBuf[offset++];

    osel_memcpy((uint8_t *)&rsp.data, &rxBuf[offset], rsp.data_length); // 根据数据长度复制数据
    offset += rsp.data_length;

    if (hart_command_rsp_ptr_arr[rsp.command] == FALSE)
    {
        return FALSE;
    }

    // 填充回复数据
    for (uint8_t i = 0; i < preamble_def; i++)
    {
        *handle->response->data_p++ = HART_PREAMBLE;
    }
    // 填充界定符
    delimiter.bits.frame_type = HART_ACK_FRAME; // 应答帧
    delimiter.bits.addr_type = delimiter_p->bits.addr_type;
    *handle->response->data_p++ = delimiter.data;
    // 填充地址
    if (delimiter.bits.addr_type == HART_DELIMITER_TYPE_SHORT)
    {
        *handle->response->data_p++ = poll_address.data;
    }
    else
    {
        osel_memcpy(handle->response->data_p, (uint8_t *)&long_address.data, HART_LONG_ADDRESS_LEN); // 长地址5个字节
        handle->response->data_p += HART_LONG_ADDRESS_LEN;
    }
    // 填充命令
    osel_memcpy(handle->response->data_p, (uint8_t *)&rsp.command, command_length);
    handle->response->data_p += command_length;

    hart_frame_data_length_start(&handle->response->data_p);
    hart_frame_response_code_start(&handle->response->data_p);
    data_start_p = handle->response->data_p;

    handle->response->code = hart_master_state_check(rsp.command); // 内部状态检查

    if (RESPONSE_COMMUNICATION_CODE_0 == handle->response->code)
    {
        if (FALSE == hart_command_rsp_ptr_arr[rsp.command](&rsp, handle->response))
        {
            return FALSE;
        }
    }

    hart_frame_data_length_end(handle->response->data_p);
    hart_frame_response_communication_code(handle->response->code);
    hart_frame_master_response_operate_code();

    // 根据载荷区数据长度判断是否需要发送
    if ((handle->response->data_p - data_start_p) > 0 || handle->response->code != RESPONSE_COMMUNICATION_CODE_0)
    {
        rsp_len = handle->response->data_p - handle->response->data;
        xor = xor_compute(&handle->response->data[preamble_def], (rsp_len - preamble_def)); // 除前导码和校验字节外所有字节的异或之后
        *handle->response->data_p++ = xor;
        rsp_len++;
        handle->response->data_length = rsp_len;
        handle->response_call(0, handle->response->data, handle->response->data_length);
    }

    return TRUE;
}

/**
 * @brief 主机初始化
 * @param {hart_master_init_t} *init
 * @return {*}
 */
BOOL hart_master_init(const hart_master_init_t *const init)
{
    if (!DBG_ASSERT(init != NULL __DBG_LINE))
        return FALSE;
    handle = (hart_master_init_t *)init;

    osel_memset((uint8_t *)&hart_master_attribute, 0, sizeof(hart_master_attribute_t));
    if (!DBG_ASSERT(hart_master_req_init(init) __DBG_LINE))
        return FALSE;

    if (!DBG_ASSERT(hart_master_rsp_init(init) __DBG_LINE))
        return FALSE;
    return TRUE;
}
#else
BOOL hart_master_handle(uint8_t *rxBuf, uint16_t len)
{
    return TRUE;
}
BOOL hart_master_init(const hart_master_init_t *const init)
{
    return TRUE;
}
#endif
